package com.ocom.accesservice.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.ocom.accesservice.dao.IDaoDeviceInfo;
import com.ocom.accesservice.service.DeviceInfoService;
import com.ocom.common.constant.UserConstants;
import com.ocom.common.dto.MachineListDto;
import com.ocom.common.entity.access.EntityMjDeviceInfo;
import com.ocom.common.entity.access.EntityMjDeviceInfoExtend;
import com.ocom.common.enums.DataSourceEnum;
import com.ocom.common.enums.MasterSlaveEnum;
import com.ocom.common.request.srvpaccess.FindMachVo;
import com.ocom.common.utils.DateUtil;
import com.ocom.common.utils.DateUtils;
import com.ocom.common.utils.StringUtils;
import com.ocom.common.vo.*;
import com.ocom.common.vo.access.MjDeviceInfoExxVo;
import com.ocom.mysql.aspect.DataSourceAspect;
import com.ocom.redis.util.RedisUtil;
import icu.mhb.mybatisplus.plugln.base.service.impl.JoinServiceImpl;
import icu.mhb.mybatisplus.plugln.core.JoinLambdaWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;


@Service
public class DeviceInfoServiceImpl extends JoinServiceImpl<IDaoDeviceInfo, EntityMjDeviceInfo> implements DeviceInfoService {

    @Autowired
    private IDaoDeviceInfo daoDeviceInfo;

    @Resource
    private RedisUtil redisUtil;


    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public List<MachineListDto> getDeviceInfo(Long areaId,Long comId) {
        QueryWrapper<EntityMjDeviceInfo> wrapper = new QueryWrapper<>();
        List<MachineListDto> list = new ArrayList<>();
        wrapper.eq("area_id", areaId);
        List<EntityMjDeviceInfo> infos = daoDeviceInfo.selectList(wrapper);
        for (EntityMjDeviceInfo entityMjDeviceInfo : infos) {
            MachineListDto machineListDto = new MachineListDto();
            //封装machineList复合域
            machineListDto.setMachID(entityMjDeviceInfo.getDeviceId());
            machineListDto.setMachName(entityMjDeviceInfo.getDeviceName());
            machineListDto.setExNumber(entityMjDeviceInfo.getDeviceNo());
            list.add(machineListDto);
        }
        return list;
    }
    //从mj_device_info表查找这些area_id对应的（comm_mode=1,2）设备信息并返回。按region_id,area_id,device_no 正向排序
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public List<EntityMjDeviceInfo> getDeviceInfo(Long comId, List<Long> areaId, Long commMode) {
        QueryWrapper<EntityMjDeviceInfo> query = Wrappers.query();
        query.eq("com_id",comId);
        query.in("area_id",areaId);
        if (commMode == 1){
            query.eq("comm_mode",commMode);
        }else {
            query.eq("comm_mode",2);
        }
        query.orderByDesc("area_id").orderByDesc("device_no");
        return daoDeviceInfo.selectList(query);

    }

    //4.根据区域id获取设备数量
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public Integer CountMachineNumber(Long areaId, Long comId) {
        QueryWrapper<EntityMjDeviceInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("area_id", areaId);
        return daoDeviceInfo.selectCount(wrapper);
    }

    @Override
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.SLAVE)
    public EntityMjDeviceInfo GetDeviceByDeviceNo(String deviceNo, Long comId) {
        QueryWrapper<EntityMjDeviceInfo> query = Wrappers.query();
        query.eq("device_no",deviceNo);
        query.last("limit 1");
        return daoDeviceInfo.selectOne(query);
    }

    /**
     * 校验设备信息是否存在
     *
     * @param companyID 公司编号
     * @param areaNo 区域编号
     * @return 结果
     */
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "companyID",isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public String checkDeviceInfoUnique(Long companyID, Long areaNo) {
        QueryWrapper<EntityMjDeviceInfo> query = Wrappers.query();
        query.eq("com_id",companyID).eq("area_id",areaNo).last("limit 1");
        //校验
        EntityMjDeviceInfo entityMjDeviceInfo = daoDeviceInfo.selectOne(query);
        //存在
        if (StringUtils.isNotNull(entityMjDeviceInfo) && areaNo.equals(entityMjDeviceInfo.getAreaId()))   {
            return UserConstants.NOT_UNIQUE;
        }
        //不存在
        return UserConstants.UNIQUE;
    }
    /**
     * 查询设备列表（searchMachList）
     * */
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public List<MjDeviceInfoExxVo> SearchMachList(SearchMachListVo searchMachListVo, Long comId) {
        JoinLambdaWrapper<EntityMjDeviceInfo> query =  new JoinLambdaWrapper<>(EntityMjDeviceInfo.class);

        if (StringUtils.isNotNull(searchMachListVo.getComId())){
            query.eq(EntityMjDeviceInfo::getComId,searchMachListVo.getComId());
        }
        if (StringUtils.isNotEmpty(searchMachListVo.getDeviceNo())){
            query.eq(EntityMjDeviceInfo::getDeviceNo,searchMachListVo.getDeviceNo());
        }
        if (StringUtils.isNotEmpty(searchMachListVo.getDeviceName())){
            query.like(EntityMjDeviceInfo::getDeviceName,searchMachListVo.getDeviceName());
        }
        if (StringUtils.isNotNull(searchMachListVo.getAreaId())){
            query.eq(EntityMjDeviceInfo::getAreaId,searchMachListVo.getAreaId());
        }
        if (StringUtils.isNotNull(searchMachListVo.getDeviceType())){
            query.eq(EntityMjDeviceInfo::getDeviceType,searchMachListVo.getDeviceType());
        }
        if (StringUtils.isNotNull(searchMachListVo.getDeviceVerType())){
            query.eq(EntityMjDeviceInfo::getDeviceVerType,searchMachListVo.getDeviceVerType());
        }
        PageHelper.startPage(searchMachListVo.getPage(), searchMachListVo.getSize());


        query.leftJoin(EntityMjDeviceInfoExtend.class, EntityMjDeviceInfoExtend::getDeviceNo, EntityMjDeviceInfo::getDeviceNo)
              .joinAnd(EntityMjDeviceInfoExtend::getComId,EntityMjDeviceInfo::getComId,0)
              .select(EntityMjDeviceInfoExtend::getUpdateWhiteInfo,
                        EntityMjDeviceInfoExtend::getWhiteErrFace,
                        EntityMjDeviceInfoExtend::getWhiteFace,
                        EntityMjDeviceInfoExtend::getWhiteUrl,
                        EntityMjDeviceInfoExtend::getWhiteUser).end();
        return this.joinList(query,MjDeviceInfoExxVo.class);
    }
    /**
     *  修改设备（updateMach）
     *
     * @return*/
    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "comId")
    @Transactional
    @Override
    public Integer UpdateMach(UpdateMachVo updateMachVo, Long comId) {
        QueryWrapper<EntityMjDeviceInfo> query = Wrappers.query();
        EntityMjDeviceInfo entityMjDeviceInfo = new EntityMjDeviceInfo();
        if (StringUtils.isNotNull(updateMachVo.getComId())){
            query.eq("com_id",updateMachVo.getComId());
            entityMjDeviceInfo.setComId(updateMachVo.getComId());
        }
        if (StringUtils.isNotNull(updateMachVo.getDeviceNo())){
            query.eq("device_no",updateMachVo.getDeviceNo());
            entityMjDeviceInfo.setDeviceNo(updateMachVo.getDeviceNo());
        }
        if (StringUtils.isNotNull(updateMachVo.getDeviceName())){
            entityMjDeviceInfo.setDeviceName(updateMachVo.getDeviceName());
        }
        if (StringUtils.isNotNull(updateMachVo.getDeviceMode())){
            entityMjDeviceInfo.setDeviceMode(updateMachVo.getDeviceMode());
        }
        if (StringUtils.isNotNull(updateMachVo.getDeviceType())){
            entityMjDeviceInfo.setDeviceType(updateMachVo.getDeviceType());
        }
        //人脸授权码
        if (StringUtils.isNotNull(updateMachVo.getFaceAuthCode())){
            entityMjDeviceInfo.setFaceAuthCode(updateMachVo.getFaceAuthCode());
        }
        //进出类型
        if (StringUtils.isNotNull(updateMachVo.getOpenType())){
            entityMjDeviceInfo.setOpenType(updateMachVo.getOpenType());
        }

        if (StringUtils.isNotNull(updateMachVo.getIfAlarm())){
            entityMjDeviceInfo.setIfAlarm(updateMachVo.getIfAlarm());
        }
        if (StringUtils.isNotNull(updateMachVo.getAlarmTimes())){
            entityMjDeviceInfo.setAlarmTimes(updateMachVo.getAlarmTimes());
        }
        entityMjDeviceInfo.setParaState(1l);
        return daoDeviceInfo.update(entityMjDeviceInfo,query);
    }
    /**
     *  修改安装位置（changeMachPlace）
     * */
    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "comId")
    @Transactional
    @Override
    public Integer ChangeMachPlace(ChangeMachPlaceVo changeMachPlaceVo, Long comId) {
        QueryWrapper<EntityMjDeviceInfo> query = Wrappers.query();
        EntityMjDeviceInfo entityMjDeviceInfo = new EntityMjDeviceInfo();
        if (StringUtils.isNotNull(changeMachPlaceVo.getComId())){
            query.eq("com_id",changeMachPlaceVo.getComId());
            entityMjDeviceInfo.setComId(changeMachPlaceVo.getComId());
        }
        if (StringUtils.isNotNull(changeMachPlaceVo.getDeviceNo())){
            query.eq("device_no",changeMachPlaceVo.getDeviceNo());
            entityMjDeviceInfo.setDeviceNo(changeMachPlaceVo.getDeviceNo());
        }
        if (StringUtils.isNotNull(changeMachPlaceVo.getAreaId())){
            entityMjDeviceInfo.setAreaId(changeMachPlaceVo.getAreaId());
        }

        entityMjDeviceInfo.setParaState(1L);
        entityMjDeviceInfo.setListState(1L);
        entityMjDeviceInfo.setListAdd(-1L);
        entityMjDeviceInfo.setListAddTab(-1L);
        entityMjDeviceInfo.setListDelete(-1L);
        entityMjDeviceInfo.setListDeleteTab(-1L);
        entityMjDeviceInfo.setGroupVer(DateUtils.dateTimeNow());

        return daoDeviceInfo.update(entityMjDeviceInfo,query);
    }
    /**
     * removeMach
     * */
    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "comId")
    @Transactional
    @Override
    public void RemoveMach(Long comId, String deviceNo) {
        QueryWrapper<EntityMjDeviceInfo> query = Wrappers.query();
        if (StringUtils.isNotNull(comId)){
            query.eq("com_id",comId);
        }
        if (StringUtils.isNotNull(deviceNo)){
            query.eq("device_no",deviceNo);
        }
        daoDeviceInfo.delete(query);
    }


    /**
     * Web按出厂号登记设备（bindMachVo）
     * @return
     */
    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "comId")
    @Transactional
    @Override
    public Integer BindMach(BindMachVo bindMachVo, Long comId) {
        EntityMjDeviceInfo entityMjDeviceInfo = new EntityMjDeviceInfo();
        if (StringUtils.isNotNull(bindMachVo.getComId())) {
            entityMjDeviceInfo.setComId(bindMachVo.getComId());
        }
        if (StringUtils.isNotNull(bindMachVo.getDeviceNo())) {
            entityMjDeviceInfo.setDeviceNo(bindMachVo.getDeviceNo());
        }
        if (StringUtils.isNotEmpty(bindMachVo.getDeviceName())) {
            entityMjDeviceInfo.setDeviceName(bindMachVo.getDeviceName());
        }
        if (StringUtils.isNotNull(bindMachVo.getDeviceType())) {
            entityMjDeviceInfo.setDeviceType(bindMachVo.getDeviceType());
        }
        if (StringUtils.isNotNull(bindMachVo.getDeviceMode())){
            entityMjDeviceInfo.setDeviceMode(bindMachVo.getDeviceMode());
        }
        if (StringUtils.isNotNull(bindMachVo.getDeviceVerType())){
            entityMjDeviceInfo.setDeviceVerType(bindMachVo.getDeviceVerType());
        }
        entityMjDeviceInfo.setStatus(bindMachVo.getStatus());
        // 设置年月日
//        Date date = new Date();
//        Calendar calendar = Calendar.getInstance();
//        calendar.setTime(date);
//        calendar.add(Calendar.YEAR, 3);
        entityMjDeviceInfo.setEndTime(DateUtils.strToDate(bindMachVo.getEndTime()));
        //area_id = 0
        //para_state = 1
        //list_state = 1
        //list_add = -1, list_add_tab = -1 ,list_delete = -1 , list_delete_tab = -1
        //group_ver = 当前时间(yyyyMMddHHmmss)
        //rsa_state = 1
        //zone_ver = 当前时间(yyyyMMddHHmmss)
        entityMjDeviceInfo.setAreaId(0L);
        entityMjDeviceInfo.setParaState(1L);
        entityMjDeviceInfo.setListState(1L);
        entityMjDeviceInfo.setListAdd(-1L);
        entityMjDeviceInfo.setListAddTab(-1L);
        entityMjDeviceInfo.setListDelete(-1L);
        entityMjDeviceInfo.setListDeleteTab(-1L);
        entityMjDeviceInfo.setRsaState(1L);
        entityMjDeviceInfo.setGroupVer(DateUtils.dateTimeNow());
        Date zoneDate = new Date();
        Calendar cZoneDate = Calendar.getInstance();
        cZoneDate.setTime(zoneDate);
        entityMjDeviceInfo.setZoneVer(DateUtil.getStrDate(cZoneDate.getTime(), DateUtils.YYYYMMDDHHMMSS));
        return daoDeviceInfo.insert(entityMjDeviceInfo);
    }



    /**
     * 删除分mj_device_Info对应记录
     */
    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "comId")
    @Transactional
    @Override
    public void DeleteMach(Long comId, String machNo) {
        QueryWrapper<EntityMjDeviceInfo> query = Wrappers.query();
        if (StringUtils.isNotEmpty(machNo)) {
            query.eq("device_no", machNo);
        }
        if (StringUtils.isNotNull(comId)) {
            query.eq("com_id", comId);
        }
        query.eq("status", 1);
        daoDeviceInfo.delete(query);
    }

    /**
     * 查询设备列表（searchMachList）
     *
     * @return*/
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public List<EntityMjDeviceInfo> FindMach(Long comId, FindMachVo findMachVo) {
        QueryWrapper<EntityMjDeviceInfo> query = Wrappers.query();
        if (StringUtils.isNotNull(findMachVo.getComId())){
            query.eq("com_id",findMachVo.getComId());
        }
        if (StringUtils.isNotEmpty(findMachVo.getDeviceNo())){
            query.eq("device_no",findMachVo.getDeviceNo());
        }
        if (StringUtils.isNotEmpty(findMachVo.getDeviceName())){
            query.like("device_name",findMachVo.getDeviceName());
        }
        PageHelper.startPage(findMachVo.getPage(),findMachVo.getSize());
        return daoDeviceInfo.selectList(query);
    }

    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public List<EntityMjDeviceInfo> FindMach2(Long comId,FindMachVo findMachVo) {
        QueryWrapper<EntityMjDeviceInfo> query = Wrappers.query();
//        if (StringUtils.isNotNull(findMachVo.getComId())){
//            query.eq("com_id",findMachVo.getComId());
//        }
        if (StringUtils.isNotEmpty(findMachVo.getDeviceNo())){
            query.eq("device_no",findMachVo.getDeviceNo());
        }
        if (StringUtils.isNotEmpty(findMachVo.getDeviceName())){
            query.like("device_name",findMachVo.getDeviceName());
        }
        if (null != findMachVo.getIfAlarm()){
            query.eq("if_alarm",findMachVo.getIfAlarm());
        }

        PageHelper.startPage(findMachVo.getPage(),findMachVo.getSize());
        return daoDeviceInfo.selectList(query);
    }
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId")
    @Transactional
    @Override
    public boolean WebImportMach(List<ImportMachVo> importMachVos, Long comId) {
        List<EntityMjDeviceInfo> entityMjDeviceInfo=new ArrayList<>();
        for(ImportMachVo importMachVo:importMachVos){
            EntityMjDeviceInfo deviceInfo = new EntityMjDeviceInfo();
            deviceInfo.setDeviceNo(importMachVo.getDeviceNo());
            deviceInfo.setComId(importMachVo.getComId());
            deviceInfo.setDeviceName(importMachVo.getDeviceNo());
            deviceInfo.setDeviceType(importMachVo.getDeviceType());

            deviceInfo.setStatus(0L);
            // 设置年月日
            Date date = new Date();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.YEAR, 3);
            deviceInfo.setEndTime(calendar.getTime());
            deviceInfo.setAreaId(0L);
            deviceInfo.setParaState(1L);
            deviceInfo.setListState(1L);
            deviceInfo.setListAdd(-1L);
            deviceInfo.setListAddTab(-1L);
            deviceInfo.setListDelete(-1L);
            deviceInfo.setListDeleteTab(-1L);
            deviceInfo.setRsaState(1L);
            deviceInfo.setGroupVer(DateUtils.dateTimeNow());
            entityMjDeviceInfo.add(deviceInfo);
        }
        return  this.saveBatch(entityMjDeviceInfo,entityMjDeviceInfo.size());
    }

    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.MASTER)
    @Override
    public void MachReset(Long comId, String machNo) {
        UpdateWrapper<EntityMjDeviceInfo> update = Wrappers.update();
        List<String> machNos = JSON.parseArray(machNo, String.class);
        update.eq("com_id",comId);
        update.in("device_no",machNos);
        update.set("list_add",-1);
        update.set("list_add_tab",-1);
        update.set("list_delete",-1);
        update.set("list_delete_tab",-1);
        update.set("list_state",1);
        update.set("para_state",1);
        this.update(update);
    }

    @Override
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.MASTER)
    public void updateMachByAlarm(Long comId, Integer alarmState, List<String> deviceNos) {
        UpdateWrapper<EntityMjDeviceInfo> update = Wrappers.update();
        update.eq("com_id",comId);
        update.in("device_no",deviceNos);

        update.set("alarm_state",alarmState);
        this.update(update);
    }

    @Override
    @DataSourceAspect(type= DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.MASTER)
    public void deleteSession(Long companyId) {
        QueryWrapper<EntityMjDeviceInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("com_id", companyId);
        List<EntityMjDeviceInfo> infos = daoDeviceInfo.selectList(wrapper);
        if(infos!=null && infos.size()>0){
            for (EntityMjDeviceInfo entityMjDeviceInfo:infos){
                redisUtil.del("HttpMjDevice:"+entityMjDeviceInfo.getDeviceNo());
            }
        }
    }
}
